home *** CD-ROM | disk | FTP | other *** search
- /**************************************************************************
- * *
- * Copyright (C) 1986, Silicon Graphics, Inc. *
- * *
- * These coded instructions, statements, and computer programs contain *
- * unpublished proprietary information of Silicon Graphics, Inc., and *
- * are protected by Federal copyright law. They may not be disclosed *
- * to third parties or copied or duplicated in any form, in whole or *
- * in part, without the prior written consent of Silicon Graphics, Inc. *
- * *
- **************************************************************************/
- #ifndef __SYS_PDA_H__
- #define __SYS_PDA_H__
-
- #ident "$Revision: 3.98 $"
-
- /*
- * sysmp(MP_STAT) structure
- */
- struct pda_stat {
- int p_cpuid; /* processor ID */
- int p_flags; /* various flags */
- };
-
- /* values for p_flags */
- #define PDAF_MASTER 0x0001
- #define PDAF_CLOCK 0x0002
- #define PDAF_ENABLED 0x0004 /* processor allowed to sched procs */
- #define PDAF_FASTCLOCK 0x0008 /* processor handles fastimer */
- #define PDAF_ISOLATED 0x0010 /* processor is isolated */
- #define PDAF_BROADCAST_OFF 0x0020 /* broadcast intr is not received */
- #define PDAF_NONPREEMPTIVE 0x0040 /* processor is not preemptive */
-
- #ifdef _KERNEL
- #include <sys/immu.h>
- #include <sys/timers.h>
- #include <sys/runq_private.h>
-
- #ifdef EVEREST
- #include <sys/EVEREST/everest.h>
- #endif
-
- /*
- * The private data area for each processor
- * Always appears at the same virtual address in each processor
- * It is one page (4K), and we use the bottom 1024 bytes as a
- * boot/idle stack.
- */
-
- /*
- * the pda itself
- */
- typedef struct pda_s {
- union {
- int dbg[4];
- struct {
- inst_t *exceptnorm; /* general exception handler */
- int filler[3];
- } common;
- } db;
- int p_cpuid; /* my processor ID */
- cpumask_t p_cpumask; /* my processor ID mask */
- int p_runrun; /* switch on return to user */
- uint p_kstackflag; /* kernel stack flag */
- k_machreg_t *p_intstack; /* base of interrupt stack */
- k_machreg_t *p_intlastframe;/* last frame on interrupt stack */
- k_machreg_t *p_bootstack; /* base of boot/idle stack */
- k_machreg_t *p_bootlastframe;/* last frame on boot/idle stack */
- int p_nested_intr; /* in nested interrupt */
- k_machreg_t p_atsave;
- k_machreg_t p_t0save;
-
- /* fields for segment table manipulation */
- k_machreg_t p_k1save; /* save k1 */
- #if OLD_SEGTBL
- caddr_t *p_gsegtbl; /* global segment table */
- #endif
-
- caddr_t p_idlstkdepth; /* store sp on interrupt on idl stack */
- int p_flags; /* various flags */
- struct proc *p_curproc; /* current process */
- int p_curpri; /* current priority */
- struct proc *p_lastproc; /* last process */
- int p_ignore; /* last process ignored by parent */
- int p_cputype_word; /* cpu rev */
- int p_fputype_word; /* fpu rev */
- int p_nofault; /* processor nofaults */
- caddr_t p_kvfault; /* processor kernel fault history */
- caddr_t p_clrkvflt[8];
- unsigned int p_hand; /* a pseodo-random value */
- struct tlbinfo *p_tlbinfo; /* tlb management info */
- struct proc *p_fpowner; /* process owning fpu */
- int p_switching; /* processor in swtch */
- int p_idleflag; /* processor idle */
- int p_idletkn; /* reasons of processor idle */
- int p_lticks; /* ticks left in time slice */
- int p_vmeipl; /* non-kmode VME interrupt level */
- int p_curlock; /* address of lock cpu is going after */
- int p_lastlock; /* addr of last lock locked */
- inst_t *p_curlockcpc; /* calling pc */
- inst_t *p_cursemcpc; /* pc invoking last semaphore op */
- int p_savespl; /* previous spl of spsemahi */
- int p_gfx_waitc; /* waiting for gfx context swtch */
- int p_gfx_waitf; /* waiting for gfx fifo */
- unsigned *prfptr; /* ptr to profiler count table */
- struct ksa *ksaptr; /* ptr to kernel system activities buf*/
- struct action_s *p_todolist; /* list of actions to do for others */
- struct action_s *p_lasttodo; /* last actions to do for others */
- int p_triggersave; /* 3-way trigger state (IP5 only) */
- /*
- * Local LED pattern maintainence.
- */
- unsigned p_led_counter;
- unsigned p_led_value;
-
- unsigned p_dbgcntdown; /* ticks between debugger checks */
- /*
- * Special modifications lock. Used to allow other processors
- * to change p_flags or p_vmeipl (to distribute functionality).
- */
- lock_t p_special;
- int p_cputype; /* 0 for IP7, 1 for IP5 (MP only) */
-
- /* for handling timein */
- int p_timein; /* set by timepoke */
- int p_ftimein; /* set by fast_timnepoke */
-
- int fclock_freq; /* freq of profiling clock */
- int p_schedflags; /* scheduling flags mod by owner only */
- struct shaddr_s *p_dispatch; /* Share group to dispatch member of */
- uint p_acvec; /* opcode vector for cpuvaction() */
- uint p_delayacvec; /* opcode vector for delay action */
- uint p_upglo; /* tlblo entry for upage */
- uint p_ukstklo; /* tlblo entry for ukstk */
- uint p_pdalo; /* tlblo entry for pda page */
- uint p_utlbmisses; /* count utlbmisses */
- uint p_sv1lo; /* tlblo entry for save of slot 1 */
- uint p_sv1lo_1; /* r4k: 2nd tlblo entry for slot 1 */
- uint p_sv1hi; /* tlbhi entry for save of slot 1 */
- uint p_sv2lo; /* tlblo entry for save of slot 2 */
- uint p_sv2lo_1; /* r4k: 2nd tlblo entry for slot 2 */
- uint p_sv2hi; /* tlbhi entry for save of slot 2 */
-
- /* scheduling values for the processor */
- #ifdef RQ_EMBEDDED
- runqpda_t p_runqpda;
- #else
- struct runqpda *p_runqpda;
- #endif
-
- /* data needed to handle IO intr */
- uint *ioep[2]; /* exception frame ptr */
- int iopend[2]; /* accumulated io pending bits */
- int preempted_iolv[2]; /* io levels being preempted */
-
- /* delay calibration info */
- int decinsperloop; /* deci-nanoseconds per 10 DELAY loop */
-
- /* floating point interrupt data */
- inst_t p_epcinst; /* instruction at epc */
- inst_t p_bdinst; /* instruction in bd slot */
-
- /* special utlbmiss handlers */
- int p_utlbmissswtch; /* index of utlbmiss handler */
- int *p_utlbmisshndlr; /* address of utlbmiss handler */
-
- /* special reserved virtual address lists for use in page_copy
- * and page_zero. Should only be used by those routines.
- */
- char p_pcopy_inuse[2];
- int *p_pcopy_pagelist[2];
- /* special reserved virtual address for use in cache operations */
- int *p_cacheop_pages;
- #if !STAT_TIME
- int p_timerstate; /* for locore */
- timer_t *p_oldtimer; /* previously active timer, for intr */
- timer_t *p_activetimer; /* points to currently active timer */
- #endif /* !STAT_TIME */
- #if JUMP_WAR
- #define JUMP_WAR_SETS 3
- #define NWIREDJUMP 3
- int p_jump_war_pte[JUMP_WAR_SETS][2*NWIREDJUMP];
- uint p_jump_war_stats[NWIREDJUMP*2];
- uint p_jump_war_set_stats[JUMP_WAR_SETS];
- uint p_jump_war_stolen;
- uint p_jump_war_set;
- uint p_max_jump_war_wired;
- #endif /* JUMP_WAR */
- uint p_rtclock_rate; /* R4k cycles/lbolt tick */
- char *p_vcelog; /* log of VCE exceptions (DEBUG) */
- int p_vcelog_offset; /* offset into log of last entry*/
- int p_vcecount; /* count of VCE exceptions */
- int p_prf_enabled; /* 1 == kernel profiling on */
- #if EVEREST
- evreg_t cmp_RTC_OBSOLETE; /* when comparator was last set */
- evreg_t last_sched_intr_RTC;
- long long counter_intr_over_sum; /* sum of cycles over norm */
- uint counter_intr_over_count;/* number of events */
- uint counter_intr_over_max; /* max cycles over norm */
- #endif /* EVEREST */
- #if EXTUSIZE == 1
- pde_t p_stackext; /* PTE for kernel stack extension */
- pde_t p_bp_stackext; /* PTE for backup kernel stack ext. */
- int p_mapstackext; /* Flag to indicate stk ext needs to be mapped */
- #endif
- } pda_t;
-
- /* UTLBMISS_* defines the bitmask of utlbmiss handlers
- * ``installed'' in each pda.
- */
- #define UTLBMISS_STD 0
- #define UTLBMISS_COUNT 1
- #define UTLBMISS_DEFER 2
-
- #define NUTLBMISS_HNDLRS 4 /* number of utlbmiss handlers */
-
- struct utlbmiss_swtch {
- int *u_start;
- int *u_end;
- };
- extern struct utlbmiss_swtch utlbmiss_swtch[];
-
- #define common_excnorm db.common.exceptnorm
-
- #if !STAT_TIME
- /* value for p_timerstate */
- #define PDA_SAVE_OLDTIMER 0x1
- #define PDA_INTTIMER_SWTCH 0x2
- #define PDA_SYSTIMER_SWTCH 0x4
- #endif
-
- /* ``run-anywhere'' value for p_mustrun */
- #define PDA_RUNANYWHERE ((cpuid_t)-1)
-
- /* values for kstackflag */
- #define PDA_CURUSRSTK 0 /* currently running on user stack */
- #define PDA_CURKERSTK 1 /* currently running on kernel user stack */
- #define PDA_CURINTSTK 2 /* currently running on interrupt stack */
- #define PDA_CURIDLSTK 3 /* currently running on idle stack */
-
- /* values for p_schedflags */
- #define PDAS_KICKIDLE 0x0001 /* do a kickidle later */
-
- typedef struct {
- int CpuId;
- pda_t *pda;
- } pdaindr_t;
-
- extern pdaindr_t pdaindr[];
- extern int numcpus; /* count of configured cpus */
- extern cpumask_t maskcpus; /* mask of configured cpus */
- extern int maxcpus; /* max configured cpus */
- extern pda_t *masterpda; /* master processor's pda */
- #ifdef MP
- extern cpuid_t getcpuid(void);
- #else
- #define getcpuid() 0
- #endif
- extern int sendintr(cpuid_t, unchar);
-
- #define PDASZ 1 /* # pages of pda */
-
- #define getpda() ((pda_t *) PDAADDR)
- #define private (*((pda_t *) PDAADDR))
- #ifdef MP
- #define cpuid() ((cpuid_t)(private.p_cpuid))
- #else
- #define cpuid() 0
- #endif
- #define cpumask() (private.p_cpumask)
-
- #ifdef MP
- #define ON_MP(X) if (maxcpus > 1) {X;}
- #define IS_MP (maxcpus > 1)
- #else
- #define ON_MP(X)
- #define IS_MP 0
- #endif
-
- /*
- * The following allows other cpus to do things for you
- */
- typedef void (*cpuacfunc_t)(void *, void *, void *, void *);
- typedef struct action_s {
- cpuacfunc_t dofunc;
- void *doarg0;
- void *doarg1;
- void *doarg2;
- void *doarg3;
- struct action_s *donext;
- } action_t;
-
- extern void actioninit(void);
- extern void cpuaction(cpuid_t, cpuacfunc_t, int , ...);
- extern void doactions(void);
- extern void cpuvaction(register cpuid_t, register uint);
- extern void doacvec(void);
- extern void da_flush_tlb(void);
-
- #define A_NOW 0x0001 /* perform this action NOW */
- #define A_QUEUE 0x0002 /* perform this action later (at disp time) */
- #define DOACTION 0xab /* argument for sendintr() to do actions */
-
- /* Opcodes for the cpu action vector */
- #if RTE
- #define VA_RTE_INTR 0x2
- #endif
- #define VA_FORCE_RESCHED 0x4
- #define VA_TRY_GANGSCHED 0x8
- #define VA_LAST_OP VA_TRY_GANGSCHED
-
- /* Opcodes for the cpu delay action vector */
- #define DA_ICACHE_FLUSH 0x1
- #define DA_TLB_FLUSH 0x2
- #define DA_LAST_OP DA_TLB_FLUSH
-
- /*
- * Process tlb management
- */
- #if JUMP_WAR
- /*
- * Permit JUMP_WAR_SETS sets of wired entries for use by the jump
- * workaround code. Each set has up to NWIREDJUMP dual-tlb entries.
- * We can accomodate any program that has 2*NWIREDJUMP-1 or fewer
- * contiguous pages with End-Of-Page jump problems. If there are
- * more than JUMP_WAR_SETS such sets of contiguous pages, performance
- * will suffer. Note that JUMP_WAR_SETS must be at least 2 to permit
- * a program executing on an "bad" page to read a distant text page
- * which is also bad.
- */
-
- #define jump_war_pte private.p_jump_war_pte
- #define jump_war_stats private.p_jump_war_stats
- #define jump_war_set_stats private.p_jump_war_set_stats
- #define jump_war_stolen private.p_jump_war_stolen
- #define jump_war_set private.p_jump_war_set
- #define max_jump_war_wired private.p_max_jump_war_wired
- #endif /* JUMP_WAR */
-
- extern lock_t tlbflushlock; /* mp tlb flush lock */
- extern unsigned char *tlbpids; /* array of NPROC * MAXCPU tlbpids */
- /* these are the array of tlbpids in use */
- /* by each process on different processors */
- /* can't be 2-dimensional array since */
- /* NPROC and MAXCPU are both tuneable */
-
- #define tlbpid(p) (*((p)->p_tlbpid + cpuid()))
- extern void check_delay_tlbflush(int);
- extern void check_delay_iflush(void);
-
- struct proc;
- extern void utlbmiss_resume(struct proc *);
- extern void wirepda(pda_t *);
- extern inst_t *get_except_norm(void);
-
- /*
- * tlbsync() flags
- */
- #define TLB_NOSLEEP 0x01
- #define STEAL_PHYSMEM 0x02
- #define NO_VADDR 0x04
- #define SPROC_TLBSYNC 0x08
- #define IMMEDIATE_BROADCAST 0x10
- #define ISOLATED_ONLY 0x20
- #define SPROC_TLBFORCE 0x40 /* force *all* cpus, including */
- /* isolated to sync tlbs */
-
- /*
- * process that is must run on isolated processor will not be paged out, nor
- * killed by sched()
- */
- #ifdef MP
- #define is_isolated(p) (p->p_flag2 & SISOLATE)
- #else
- #define is_isolated(p) (0)
- #endif
- #define isomask(p) ((((p)->p_shaddr) && ((p)->p_shmask & PR_SADDR)) ? \
- (p)->p_shaddr->s_isomask : (cpumask_t)0)
-
- /* flags for check_delay_tlbflush() */
- #define ENTRANCE 0
- #define EXIT 1
-
- #ifdef MP
- #define CHECK_DELAY_TLBFLUSH(flag) {\
- if (private.p_flags & PDAF_ISOLATED) \
- check_delay_tlbflush(flag); \
- }
-
- #define CHECK_DELAY_IFLUSH() {\
- if (private.p_flags & PDAF_ISOLATED) \
- check_delay_iflush(); \
- }
- #else
- #define CHECK_DELAY_TLBFLUSH(x)
- #define CHECK_DELAY_IFLUSH()
- #endif
-
- #endif /* _KERNEL */
-
- #endif /* __SYS_PDA_H__ */
-